import xbmc
import xbmcgui
import xbmcaddon
import urllib
import urllib2
import re
import os
import time
import cgi
import sys
import httplib
import urlparse
import gzip

# Global settings
__plugin__		= "MyTVand.Me"
__version__		= "1.0.6"
__settings__ 	= xbmcaddon.Addon(id="script.mytvandme")
__apiurl__ 	= 'www.mytvand.me'
__apipath__ 	= '/upload'

DB_FFILE = xbmc.translatePath('special://home/userdata/Database/MyVideos60.db')
GZ_FFILE = xbmc.translatePath('special://home/userdata/Database/MyTVandMeDatabase.db.gz')

# Debugging info
print "[ADDON] '%s: version %s' initialized!" % (__plugin__, __version__)

# Send a notice.  Specify message and duration.
def sendNotice(msg,force):
	if (__settings__.getSetting("notifications") == 'true' or force == 1):
		xbmc.executebuiltin('Notification(' + __plugin__ + ',' + msg + ',6000,' + __settings__.getAddonInfo("icon") + ')')

def debug(message):	
	if (__settings__.getSetting("debug") == 'true'):
		message = "MyTVand.Me: " + message
		print message

# The following function is modified from the snippet at:
# http://code.activestate.com/recipes/146306/
def encode_multipart_formdata(fields, files=()):
	"""
	fields is a dictionary of name to value for regular form fields.
	files is a sequence of (name, filename, value) elements for data to be
	uploaded as files.
	Return (content_type, body) ready for httplib.HTTP instance
	"""
	BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
	CRLF = '\r\n'
	L = []
	for key, value in fields.items():
		L.append('--' + BOUNDARY)
		L.append('Content-Disposition: form-data; name="%s"' % key)
		L.append('')
		L.append(value)
	for (key, filename, value) in files:
		L.append('--' + BOUNDARY)
		L.append('Content-Disposition: form-data; name="%s"; filename="%s"' %
				 (key, filename))
		content_type = 'application/octet-stream'
		L.append('Content-Type: %s' % content_type)
		L.append('')
		L.append(value)
	L.append('--' + BOUNDARY + '--')
	L.append('')
	body = CRLF.join(L)
	content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
	return content_type, body

def post_multipart(host, selector, fields, files):
	content_type, body = encode_multipart_formdata(fields, files)
	h = httplib.HTTPConnection(host)
	headers = {
		'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/A.B (KHTML, like Gecko) Chrome/X.Y.Z.W Safari/A.B.',
		'Content-Type': content_type
		}
	code = '404'
	h.request('POST', selector, body, headers)
	res = h.getresponse()
	code = res.read()
	return code

def sendReq(username, password):
	debug("Opening Database File.")
	f_in = open(DB_FFILE, 'rb')
	f_out = gzip.open(GZ_FFILE, 'wb')
	debug("Zipping database file.")
	f_out.writelines(f_in)
	f_out.close()
	f_in.close()
	values = {'username':username,'password':password}
	files = [('upfile', "MyTVandMeDatabase.db.gz", open(GZ_FFILE, 'rb').read())]
	debug("Uploading Database")
	maxtries = 3
	tries = 1
	data = "404"
	while(tries <= maxtries):
		try:
			data=post_multipart(__apiurl__,__apipath__, values, files)
			tries = maxtries + 1
		except:
			tries = tries + 1
			debug('Error uploading attempt no. ' + tries)
	
	return data
  
def sendUpdate():
	username = __settings__.getSetting("username")
	password = __settings__.getSetting("password")
	if (username == '' or password == ''):
		sendNotice("Configure your account details before submitting.", 1)
		return
		
	code = sendReq(username, password)
	debug(code)

	if code == '117':
		sendNotice("Update sent successfully", 0)
	elif code == '1040':
		sendNotice("Invalid Username/Password", 1)
	elif code == '500':
		sendNotice("No File Uploaded", 0)
	elif code == '404':
		sendNotice("HTTP Error", 0)
	elif code == '666':
		sendNotice("File System Error", 0)
	else: sendNotice("Unspecified Error", 0)
      
def getModDate():
	return os.stat(DB_FFILE).st_mtime

def waiter(seconds):
	debug('waiting ' + str(seconds) + ' secs')
	for i in range(1, seconds):
		time.sleep(1)
		if xbmc.abortRequested == True:
			sys.exit()
			
# Main execution path	
startup = False
oldModDate = getModDate()
intervalDelay = __settings__.getSetting("updateInt")
updateDelay = 60
autorun = False

try:
	count = len(sys.argv) - 1
	if (sys.argv[1] == '-startup'):
		startup = True
except:
	pass

if (__settings__.getSetting( "autorun" ) == 'true'):
	autorun = True

# If triggered from programs menu
if (not startup):
	debug('Triggered from programs menu, setting autostart option and running once')
	sendUpdate()
	

debug('Waiting to send updates')
if (autorun):
	while 1:
		newModDate = getModDate()
		debug('Checking for library updates')
		debug("saved timestamp   " + str(oldModDate))
		debug("current timestamp " + str(newModDate))
		
		if oldModDate == newModDate:
			debug('No change in Timestamp')
			waiter(intervalDelay)
		else:		
			while (oldModDate != newModDate):
				debug('Change in timestamp, sleep to let update finish')
				waiter(updateDelay)
				oldModDate = newModDate
				newModDate = getModDate()
			
			debug('timestamp stopped changing, sending update now')
			sendUpdate()
			waiter(intervalDelay)